package hudson.plugins.disk_usage.integration;
import java.util.ConcurrentModificationException;
import java.util.GregorianCalendar;
import hudson.model.FreeStyleBuild;
import hudson.util.XStream2;
import hudson.model.AbstractBuild;
import hudson.matrix.MatrixBuild;
import hudson.model.TopLevelItem;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.Annotation;
import org.jvnet.hudson.test.JenkinsRecipe;
import hudson.XmlFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import hudson.model.AbstractProject;
import java.io.IOException;
import org.jvnet.hudson.test.recipes.LocalData;
import java.io.PrintStream;
import hudson.FilePath;
import hudson.tasks.Shell;
import hudson.plugins.disk_usage.*;
import java.io.File;
import java.util.Map;
import java.util.Set;
import hudson.model.listeners.RunListener;
import hudson.model.Slave;
import org.junit.Test;
import hudson.matrix.MatrixConfiguration;
import hudson.matrix.AxisList;
import hudson.matrix.TextAxis;
import hudson.matrix.MatrixProject;
import hudson.model.FreeStyleProject;
import hudson.model.Items;
import hudson.model.Run;
import hudson.slaves.OfflineCause;
import org.junit.Rule;
import org.jvnet.hudson.test.JenkinsRule;
import static org.junit.Assert.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.METHOD;
import static org.mockito.Mockito.*;
/**
*
* @author Lucie Votypkova
*/
public class DiskUsagePropertyTest {
@Rule
public JenkinsRule j = new JenkinsRule();
@Test
public void testGetAllDiskUsageWithoutBuilds() throws Exception{
FreeStyleProject project = j.jenkins.createProject(FreeStyleProject.class, "project1");
MatrixProject matrixProject = j.jenkins.createProject(MatrixProject.class, "project2");
TextAxis axis1 = new TextAxis("axis", "axisA");
TextAxis axis2 = new TextAxis("axis2", "Aaxis");
AxisList list = new AxisList();
list.add(axis1);
list.add(axis2);
matrixProject.setAxes(list);
Long sizeOfProject = 7546l;
Long sizeOfMatrixProject = 6800l;
DiskUsageProperty projectProperty = project.getProperty(DiskUsageProperty.class);
//project.addProperty(projectProperty);
projectProperty.setDiskUsageWithoutBuilds(sizeOfProject);
DiskUsageProperty matrixProjectProperty = matrixProject.getProperty(DiskUsageProperty.class);
matrixProjectProperty.setDiskUsageWithoutBuilds(sizeOfMatrixProject);
long size1 = 5390;
int count = 1;
Long matrixProjectTotalSize = sizeOfMatrixProject;
for(MatrixConfiguration c: matrixProject.getItems()){
DiskUsageProperty configurationProperty = c.getProperty(DiskUsageProperty.class);
if(configurationProperty == null){
configurationProperty = new DiskUsageProperty();
c.addProperty(configurationProperty);
}
configurationProperty.setDiskUsageWithoutBuilds(count*size1);
matrixProjectTotalSize += count*size1;
count++;
}
matrixProject.getAction(ProjectDiskUsageAction.class).actualizeCashedJobWithoutBuildsData();
project.getAction(ProjectDiskUsageAction.class).actualizeCashedJobWithoutBuildsData();
assertEquals("DiskUsageProperty for FreeStyleProject " + project.getDisplayName() + " returns wrong value its size without builds and including sub-projects.", sizeOfProject, project.getProperty(DiskUsageProperty.class).getAllDiskUsageWithoutBuilds());
assertEquals("DiskUsageProperty for MatrixProject " + matrixProject.getDisplayName() + " returns wrong value for its size without builds and including sub-projects.", matrixProjectTotalSize, matrixProject.getProperty(DiskUsageProperty.class).getAllDiskUsageWithoutBuilds());
}
@Test
public void testCheckWorkspaces() throws Exception{
//turn off run listener
RunListener listener = RunListener.all().get(DiskUsageBuildListener.class);
j.jenkins.getExtensionList(RunListener.class).remove(listener);
Slave slave1 = j.createOnlineSlave();
Slave slave2 = j.createOnlineSlave();
FreeStyleProject project = j.jenkins.createProject(FreeStyleProject.class, "project");
DiskUsageProperty prop = project.getProperty(DiskUsageProperty.class);
project.setAssignedLabel(slave1.getSelfLabel());
j.buildAndAssertSuccess(project);
Set<String> nodes = prop.getSlaveWorkspaceUsage().keySet();
project.setAssignedLabel(slave2.getSelfLabel());
j.buildAndAssertSuccess(project);
prop.getSlaveWorkspaceUsage().keySet();
project.getBuildByNumber(1).delete();
prop.getDiskUsage().removeNode(slave1);
project.getProperty(DiskUsageProperty.class);
if(prop == null){
prop = new DiskUsageProperty();
project.addProperty(prop);
}
prop.getSlaveWorkspaceUsage().keySet();
prop.checkWorkspaces();
prop.getSlaveWorkspaceUsage().keySet();
assertTrue("DiskUsage property should contains slave " + slave2.getDisplayName() + " in slaveWorkspaceUsage.", nodes.contains(slave2.getNodeName()));
assertFalse("DiskUsage property should not contains slave " + slave1.getDisplayName() + " in slaveWorkspaceUsage when detection of user workspace withour reference from project is not set.", nodes.contains(slave1.getNodeName()));
j.jenkins.getPlugin(DiskUsagePlugin.class).getConfiguration().setCheckWorkspaceOnSlave(true);
prop.checkWorkspaces();
assertTrue("DiskUsage property should contains slave " + slave2.getDisplayName() + " in slaveWorkspaceUsage.", nodes.contains(slave2.getNodeName()));
assertTrue("DiskUsage property should contains slave " + slave1.getDisplayName() + " in slaveWorkspaceUsage when detection of user workspace withour reference from project is set.", nodes.contains(slave1.getNodeName()));
j.jenkins.getPlugin(DiskUsagePlugin.class).getConfiguration().setCheckWorkspaceOnSlave(false);
}
@Test
public void getWorkspaceSizeTest() throws Exception{
RunListener listener = RunListener.all().get(DiskUsageBuildListener.class);
j.jenkins.getExtensionList(RunListener.class).remove(listener);
Slave slave1 = DiskUsageTestUtil.createSlave("slave1", new File(j.jenkins.getRootDir(),"workspace1").getPath(), j.jenkins, j.createComputerLauncher(null));
Slave slave2 = DiskUsageTestUtil.createSlave("slave2", new File(j.jenkins.getRootDir(),"workspace2").getPath(), j.jenkins, j.createComputerLauncher(null));
FreeStyleProject project = j.jenkins.createProject(FreeStyleProject.class, "project");
project.setAssignedLabel(slave1.getSelfLabel());
j.buildAndAssertSuccess(project);
project.setAssignedLabel(slave2.getSelfLabel());
j.buildAndAssertSuccess(project);
project.setCustomWorkspace(j.jenkins.getRootDir().getAbsolutePath() + "/project-custom-workspace");
j.buildAndAssertSuccess(project);
DiskUsageProperty prop = project.getProperty(DiskUsageProperty.class);
if(prop == null){
prop = new DiskUsageProperty();
project.addProperty(prop);
}
prop.checkWorkspaces();
Long workspaceSize = 7509l;
Map<String,Map<String,Long>> diskUsage = prop.getSlaveWorkspaceUsage();
for(String name : diskUsage.keySet()){
Map<String,Long> slaveInfo = diskUsage.get(name);
for(String path: slaveInfo.keySet()){
slaveInfo.put(path, workspaceSize);
}
}
assertEquals("DiskUsage workspaces which is configured as slave workspace is wrong.", workspaceSize*2, prop.getWorkspaceSize(true), 0);
assertEquals("DiskUsage workspaces which is not configured as slave workspace is wrong.", workspaceSize, prop.getWorkspaceSize(false), 0);
}
@Test
public void testchcekWorkspacesIfSlaveIsDeleted() throws Exception{
FreeStyleProject project = j.jenkins.createProject(FreeStyleProject.class, "project");
DiskUsageProperty property = new DiskUsageProperty();
project.addProperty(property);
Slave slave1 = j.createOnlineSlave();
Slave slave2 = j.createOnlineSlave();
FilePath path = j.jenkins.getWorkspaceFor(project);
path.mkdirs();
property.putSlaveWorkspaceSize(j.jenkins, path.getRemote(), 10495l);
property.putSlaveWorkspaceSize(slave1,slave1.getRemoteFS(),5670l);
property.putSlaveWorkspaceSize(slave2, slave2.getRemoteFS(), 7987l);
j.jenkins.removeNode(slave2);
property.checkWorkspaces();
assertFalse("Disk usage property should not contains slave which does not exist.", property.getSlaveWorkspaceUsage().containsKey(slave2.getNodeName()));
assertTrue("Disk usage property should contains slave1.", property.getSlaveWorkspaceUsage().containsKey(slave1.getNodeName()));
assertTrue("Disk usage property should contains jenkins master.", property.getSlaveWorkspaceUsage().containsKey(j.jenkins.getNodeName()));
}
@Test
public void testchcekWorkspacesIfDoesNotExistsIsDeleted() throws Exception{
FreeStyleProject project = j.jenkins.createProject(FreeStyleProject.class, "project");
DiskUsageProperty property = new DiskUsageProperty();
project.addProperty(property);
Slave slave1 = j.createOnlineSlave();
Slave slave2 = j.createOnlineSlave();
FilePath path = j.jenkins.getWorkspaceFor(project);
path.mkdirs();
property.putSlaveWorkspaceSize(j.jenkins, path.getRemote(), 10495l);
property.putSlaveWorkspaceSize(slave1, slave1.getRemoteFS() + "/project", 5670l);
property.putSlaveWorkspaceSize(slave2, slave2.getRemoteFS(), 7987l);
property.checkWorkspaces();
assertFalse("Disk usage property should not contains slave which does not have any workspace for its project.", property.getSlaveWorkspaceUsage().containsKey(slave1.getNodeName()));
assertTrue("Disk usage property should contains slave2.", property.getSlaveWorkspaceUsage().containsKey(slave2.getNodeName()));
assertTrue("Disk usage property should contains jenkins master.", property.getSlaveWorkspaceUsage().containsKey(j.jenkins.getNodeName()));
path.delete();
property.checkWorkspaces();
assertFalse("Disk usage property should contains jenkins master, because workspace for its project was deleted.", property.getSlaveWorkspaceUsage().containsKey(j.jenkins.getNodeName()));
}
@Test
public void testGetAllNonSlaveOrCustomWorkspaceSizeWithOnlySlaves() throws Exception{
FreeStyleProject project = j.jenkins.createProject(FreeStyleProject.class, "project");
project.getBuildersList().add(new Shell("echo hello > log"));
Slave slave3 = DiskUsageTestUtil.createSlave("slave3", new File(j.jenkins.getRootDir(),"SlaveWorkspace").getPath(), j.jenkins, j.createComputerLauncher(null));
Slave slave1 = j.createOnlineSlave();
Slave slave2= j.createOnlineSlave();
File workspaceSlave1 = new File(slave3.getRemoteFS(), project.getName()+ "/log");
//DiskUsageTestUtil.createFileWithContent(workspaceSlave1);
File workspaceSlave2 = new File(slave1.getRemoteFS(), project.getName() + "/log");
//DiskUsageTestUtil.createFileWithContent(workspaceSlave2);
File customWorkspaceSlave1 = new File(j.jenkins.getRootDir(),"custom2/log");
//DiskUsageTestUtil.createFileWithContent(customWorkspaceSlave1);
File customWorkspaceSlave2 = new File(j.jenkins.getRootDir(),"custom1/log");
//DiskUsageTestUtil.createFileWithContent(customWorkspaceSlave2);
project.setAssignedLabel(slave3.getSelfLabel());
j.buildAndAssertSuccess(project);
project.setCustomWorkspace(customWorkspaceSlave1.getParentFile().getAbsolutePath());
j.buildAndAssertSuccess(project);
project.setCustomWorkspace(null);
project.setAssignedLabel(slave2.getSelfLabel());
j.buildAndAssertSuccess(project);
project.setCustomWorkspace(customWorkspaceSlave2.getParentFile().getAbsolutePath());
j.buildAndAssertSuccess(project);
Long customWorkspaceSlaveSize = customWorkspaceSlave1.length() + customWorkspaceSlave2.length() + customWorkspaceSlave1.getParentFile().length() + customWorkspaceSlave2.getParentFile().length();
assertEquals("", customWorkspaceSlaveSize, project.getProperty(DiskUsageProperty.class).getAllNonSlaveOrCustomWorkspaceSize(), 0);
//take one slave offline
slave1.toComputer().disconnect(new OfflineCause.ByCLI("test disconnection"));
assertEquals("", customWorkspaceSlaveSize, project.getProperty(DiskUsageProperty.class).getAllNonSlaveOrCustomWorkspaceSize(), 0);
//change remote fs
slave3 = DiskUsageTestUtil.createSlave("slave3", new File(j.jenkins.getRootDir(),"ChangedWorkspace").getPath(), j.jenkins, j.createComputerLauncher(null));
customWorkspaceSlaveSize = customWorkspaceSlaveSize + workspaceSlave1.length();
assertEquals("", customWorkspaceSlaveSize, project.getProperty(DiskUsageProperty.class).getAllNonSlaveOrCustomWorkspaceSize(), 0);
}
@Test
public void testGetAllNonSlaveOrCustomWorkspaceSizeWithMaster() throws Exception{
FreeStyleProject project = j.jenkins.createProject(FreeStyleProject.class, "project");
project.getBuildersList().add(new Shell("echo hello > log"));
Slave slave1 = j.createOnlineSlave();
File workspaceSlave2 = new File(slave1.getRemoteFS(), project.getName() + "/log");
File customWorkspaceSlave1 = new File(j.jenkins.getRootDir(),"custom2/log");
File customWorkspaceSlave2 = new File(j.jenkins.getRootDir(),"custom1/log");
j.jenkins.setNumExecutors(1);
project.setAssignedLabel(j.jenkins.getSelfLabel());
j.buildAndAssertSuccess(project);
project.setCustomWorkspace(customWorkspaceSlave1.getParentFile().getAbsolutePath());
j.buildAndAssertSuccess(project);
project.setCustomWorkspace(null);
project.setAssignedLabel(slave1.getSelfLabel());
j.buildAndAssertSuccess(project);
project.setCustomWorkspace(customWorkspaceSlave2.getParentFile().getAbsolutePath());
j.buildAndAssertSuccess(project);
Long customWorkspaceSlaveSize = customWorkspaceSlave1.length() + customWorkspaceSlave2.length() + customWorkspaceSlave1.getParentFile().length() + customWorkspaceSlave2.getParentFile().length();
assertEquals("", customWorkspaceSlaveSize, project.getProperty(DiskUsageProperty.class).getAllNonSlaveOrCustomWorkspaceSize(), 0);
//take one slave offline
j.jenkins.setNumExecutors(0);
assertEquals("", customWorkspaceSlaveSize, project.getProperty(DiskUsageProperty.class).getAllNonSlaveOrCustomWorkspaceSize(), 0);
}
@Test
@LocalData
public void testBackwadrCompatibility1() throws IOException{
try {
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
j.jenkins.getPlugin(DiskUsagePlugin.class).getConfiguration().disableBuildsDiskUsageCalculation();
j.jenkins.getPlugin(DiskUsagePlugin.class).getConfiguration().disableJobsDiskUsageCalculation();
j.jenkins.getPlugin(DiskUsagePlugin.class).getConfiguration().disableWorkspacesDiskUsageCalculation();
//should load all builds
project.getBuildsAsMap().size();
assertEquals("Size of project1 should be loaded from previous configuration.", 188357L, property.getAllDiskUsageWithoutBuilds(), 0);
assertEquals("Size of build 3 should be loaded from previous configuration.", 23932L, property.getDiskUsageOfBuild(3), 0);
} catch (Exception ex) {
Logger.getLogger(DiskUsagePropertyTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Test
@ReplaceHudsonHomeWithCurrentPath("jobs/project1/config.xml")
@LocalData
public void testBackwadrCompatibility2() throws IOException{
j.jenkins.getPlugin(DiskUsagePlugin.class).getConfiguration().disableBuildsDiskUsageCalculation();
j.jenkins.getPlugin(DiskUsagePlugin.class).getConfiguration().disableJobsDiskUsageCalculation();
j.jenkins.getPlugin(DiskUsagePlugin.class).getConfiguration().disableWorkspacesDiskUsageCalculation();
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
//load all builds
project.getBuildsAsMap().size();
assertEquals("Size of project1 should be loaded from previous configuration.", 188357L, property.getAllDiskUsageWithoutBuilds(), 0);
assertEquals("Size of workspaces should be loaded from previous configuration.",4096, property.getAllWorkspaceSize(), 0);
assertTrue("Path of workspace shoudl be loaded form previous configuration.", property.getSlaveWorkspaceUsage().get("").containsKey(j.jenkins.getRootDir().getAbsolutePath() + "/workspace"));
}
@Test
@LocalData
public void testGetDiskUsageOfBuilds(){
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
int loadedBuildsSize = project._getRuns().getLoadedBuilds().size();
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
for(DiskUsageBuildInformation information : property.getDiskUsageOfBuilds()){
assertEquals("Disk usage of build has loaded wrong size.", information.getNumber()*1000, information.getSize(), 0);
}
assertEquals("No build should be loaded.", loadedBuildsSize, project._getRuns().getLoadedBuilds().size(), 0);
}
@Test
@LocalData
public void testGetDiskUsageOfBuild(){
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
int loadedBuildsSize = project._getRuns().getLoadedBuilds().size();
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
assertEquals("Build with id 1 should have size 3000", 3000, property.getDiskUsageOfBuild("2013-08-09_13-02-27"), 0);
assertEquals("Build with id 10 should have size 10000", 10000, property.getDiskUsageOfBuild("2013-08-09_13-03-05"), 0);
assertEquals("No build should be loaded.", loadedBuildsSize, project._getRuns().getLoadedBuilds().size(), 0);
}
@Test
@LocalData
public void testGetDiskUsageBuildInformation(){
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
int loadedBuildsSize = project._getRuns().getLoadedBuilds().size();
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
assertEquals("Build with id 1 should have size 3000", 3000, property.getDiskUsageBuildInformation("2013-08-09_13-02-27").getSize(), 0);
assertEquals("Build with id 10 should have size 10000", 10000, property.getDiskUsageBuildInformation("2013-08-09_13-03-05").getSize(), 0);
assertEquals("No build should be loaded.", loadedBuildsSize, project._getRuns().getLoadedBuilds().size(), 0);
}
@Test
@LocalData
public void testGetDiskUsageOfBuildByNumber(){
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
int loadedBuildsSize = project._getRuns().getLoadedBuilds().size();
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
assertEquals("Build with id 1 should have size 3000", 3000, property.getDiskUsageOfBuild(3), 0);
assertEquals("Build with id 10 should have size 10000", 10000, property.getDiskUsageOfBuild(10), 0);
assertEquals("No build should be loaded.", loadedBuildsSize, project._getRuns().getLoadedBuilds().size(), 0);
}
@Test
@ReplaceHudsonHomeWithCurrentPath("jobs/project1/disk-usage.xml")
@LocalData
public void testCheckWorkspacesBuildsWithoutLoadingBuilds() throws IOException, InterruptedException {
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
int loadedBuildsSize = project._getRuns().getLoadedBuilds().size();
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
FilePath f = j.jenkins.getWorkspaceFor((TopLevelItem)project);
property.checkWorkspaces();
assertEquals("Workspace should have size 4096", 4096, property.getAllWorkspaceSize(), 0);
assertEquals("No build should be loaded.", loadedBuildsSize, project._getRuns().getLoadedBuilds().size(), 0);
}
@Test
@ReplaceHudsonHomeWithCurrentPath("jobs/project1/config.xml, jobs/project1/builds/2013-08-09_13-02-27/build.xml, jobs/project1/builds/2013-08-09_13-02-28/build.xml")
@LocalData
public void testCheckWorkspacesWithLoadingBuilds() throws IOException {
File file = new File(j.jenkins.getRootDir(),"jobs/project2/builds/2013-08-09_13-02-26/build.xml");
XmlFile f = new XmlFile(new XStream2(), file);
String newBuildXml = f.asString().replace("${JENKINS_HOME}",j.jenkins.getRootDir().getAbsolutePath());
PrintStream st = new PrintStream(file);
st.print(newBuildXml);
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
AbstractProject project2 = (AbstractProject) j.jenkins.getItem("project2");
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
DiskUsageProperty property2 = (DiskUsageProperty) project2.getProperty(DiskUsageProperty.class);
property2.getDiskUsage().loadAllBuilds(true);
assertTrue("Project should contains workspace with path {JENKINS_HOME}/jobs/project1/workspace", property.getSlaveWorkspaceUsage().get("").containsKey("${JENKINS_HOME}/jobs/project1/workspace"));
assertTrue("Project should contains workspace with path {JENKINS_HOME}/workspace", property2.getSlaveWorkspaceUsage().get("").containsKey(j.jenkins.getRootDir().getAbsolutePath() + "/workspace"));
assertEquals("Builds should be loaded.", 2, project2._getRuns().getLoadedBuilds().size(), 0);
}
@Test
public void testGetAllDiskUsageOfBuild() throws IOException, Exception{
; FreeStyleProject project = j.jenkins.createProject(FreeStyleProject.class, "project1");
MatrixProject matrixProject = j.jenkins.createProject(MatrixProject.class, "project2");
TextAxis axis1 = new TextAxis("axis", "axisA", "axisB", "axisC");
TextAxis axis2 = new TextAxis("axis2", "Aaxis", "Baxis", "Caxis");
AxisList list = new AxisList();
list.add(axis1);
list.add(axis2);
matrixProject.setAxes(list);
j.buildAndAssertSuccess(project);
AbstractBuild build = project.getLastBuild();
j.buildAndAssertSuccess(matrixProject);
MatrixBuild matrixBuild1 = matrixProject.getLastBuild();
j.buildAndAssertSuccess(matrixProject);
MatrixBuild matrixBuild2 = matrixProject.getLastBuild();
Long sizeofBuild = 7546l;
Long sizeOfMatrixBuild1 = 6800l;
Long sizeOfMatrixBuild2 = 14032l;
DiskUsageTestUtil.getBuildDiskUsageAction(build).setDiskUsage(sizeofBuild);
DiskUsageTestUtil.getBuildDiskUsageAction(matrixBuild1).setDiskUsage(sizeOfMatrixBuild1);
DiskUsageTestUtil.getBuildDiskUsageAction(matrixBuild2).setDiskUsage(sizeOfMatrixBuild2);
long size1 = 5390;
long size2 = 2390;
int count = 1;
Long matrixBuild1TotalSize = sizeOfMatrixBuild1;
Long matrixBuild2TotalSize = sizeOfMatrixBuild2;
for(MatrixConfiguration c: matrixProject.getItems()){
AbstractBuild configurationBuild = c.getBuildByNumber(1);
DiskUsageTestUtil.getBuildDiskUsageAction(configurationBuild).setDiskUsage(count*size1);
matrixBuild1TotalSize += count*size1;
AbstractBuild configurationBuild2 = c.getBuildByNumber(2);
DiskUsageTestUtil.getBuildDiskUsageAction(configurationBuild2).setDiskUsage(count*size2);
matrixBuild2TotalSize += count*size2;
count++;
}
hudson.plugins.disk_usage.DiskUsageProperty freeStyleProjectProperty = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
DiskUsageProperty matrixProjectProperty = (DiskUsageProperty) matrixProject.getProperty(DiskUsageProperty.class);
assertEquals("BuildDiskUsageAction for build 1 of FreeStyleProject " + project.getDisplayName() + " returns wrong value for its size including sub-builds.", sizeofBuild, freeStyleProjectProperty.getAllDiskUsageOfBuild(1));
assertEquals("BuildDiskUsageAction for build 1 of MatrixProject " + matrixProject.getDisplayName() + " returns wrong value for its size including sub-builds.", matrixBuild1TotalSize, matrixProjectProperty.getAllDiskUsageOfBuild(1));
assertEquals("BuildDiskUsageAction for build 2 of MatrixProject " + matrixProject.getDisplayName() + " returns wrong value for its size including sub-builds.", matrixBuild2TotalSize, matrixProjectProperty.getAllDiskUsageOfBuild(2));
}
@Test
@LocalData
public void testDoNotBreakLazyLoading(){
AbstractProject project = (AbstractProject) j.jenkins.getItem("project1");
int loadedBuilds = project._getRuns().getLoadedBuilds().size();
assertTrue("This tests does not sense if there are loaded all builds.",8>loadedBuilds);
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
assertEquals("Size of builds should be loaded.", 1000, property.getAllDiskUsageOfBuild(1), 0);
assertEquals("Size of builds should be loaded.", 7000, property.getAllDiskUsageOfBuild(7), 0);
assertTrue("No new build should be loaded.", loadedBuilds <= project._getRuns().getLoadedBuilds().size());
}
@Test
public void testRemoveBuild() throws Exception{
FreeStyleProject project = j.createFreeStyleProject();
j.buildAndAssertSuccess(project);
j.buildAndAssertSuccess(project);
DiskUsageProperty property = project.getProperty(DiskUsageProperty.class);
assertEquals("Disk usage should have information about two builds.", 2, property.getDiskUsage().getBuildDiskUsage(false).size());
AbstractBuild build = project.getLastBuild();
build.delete();
assertEquals("Deleted build should be removed from disk-usage informations too.", 1, property.getDiskUsage().getBuildDiskUsage(false).size());
}
@Test
public void testRemoveDeletedBuildNotLoadedByJenkins() throws Exception{
FreeStyleProject project = j.createFreeStyleProject();
j.buildAndAssertSuccess(project);
j.buildAndAssertSuccess(project);
AbstractBuild build = project.getLastBuild();
File file = build.getRootDir();
FilePath path = new FilePath(file);
path.deleteRecursive();
DiskUsageProperty property = project.getProperty(DiskUsageProperty.class);
assertFalse("It is not possible to delete build.", file.exists());
assertEquals("Disk usage should have information about 2 builds.", 2, property.getDiskUsage().getBuildDiskUsage(false).size());
j.jenkins.reload();
project = (FreeStyleProject) j.jenkins.getItem(project.getDisplayName());
property = project.getProperty(DiskUsageProperty.class);
assertEquals("Deleted build without Jenkins should not be loaded.", 1, property.getDiskUsage().getBuildDiskUsage(false).size());
}
private TestThread runRemoveThread(ProjectDiskUsage usage){
final ProjectDiskUsage diskUsage = usage;
TestThread removeThread = new TestThread("removeFromSet"){
public void run(){
try{
int count = 0;
while(count < 1000){
count++;
diskUsage.removeBuild(diskUsage.getDiskUsageBuildInformation(count));
}
} catch (ConcurrentModificationException ex) {
exception = ex;
}catch (Exception ex){
exception = ex;
}
}
};
removeThread.start();
return removeThread;
}
private TestThread runPutThread(ProjectDiskUsage usage){
final ProjectDiskUsage diskUsage = usage;
TestThread putThread = new TestThread("putIntoSet"){
public void run(){
try {
int count = 0;
while(count < 1000){
count++;
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(2014, 1, 1);
calendar.add(GregorianCalendar.MINUTE, count);
Run.ID_FORMATTER.get().format(calendar.getTime());
diskUsage.addBuildInformation(new DiskUsageBuildInformation(Run.ID_FORMATTER.get().format(calendar.getTime()),calendar.getTimeInMillis(), count, 0l), null);
}
} catch (ConcurrentModificationException ex) {
exception = ex;
}catch (Exception ex){
exception = ex;
}
}
};
putThread.start();
return putThread;
}
private TestThread runSaveThread(ProjectDiskUsage usage){
final ProjectDiskUsage diskUsage = usage;
TestThread saveThread = new TestThread("saveSet"){
public void run(){
try{
int count = 0;
while(count<100){
count++;
diskUsage.save();
}
} catch (ConcurrentModificationException ex) {
exception = ex;
}catch (Exception ex){
exception = ex;
}
}
};
saveThread.start();
return saveThread;
}
private void checkForConcurrencyException(Exception exception){
exception.printStackTrace(System.err);
if(exception instanceof ConcurrentModificationException){
fail("DiskUsageProperty is not thread save. Attribute #diskUsageProperty caused ConcurrentModitifiactionException");
return;
}
fail("Checking of thread safety caused Exception which is not connected with thread safety problem.");
}
//JENKINS-29143
@Test
public void testThreadSaveOperationUnderSetOfDiskUsageBuildInformation() throws Exception{
final FreeStyleProject project = j.createFreeStyleProject();
final ProjectDiskUsage diskUsage = new ProjectDiskUsage();
diskUsage.setProject(project);
TestThread putThread = runPutThread(diskUsage);
TestThread removeThread = runRemoveThread(diskUsage);
TestThread saveThread = runSaveThread(diskUsage);
while(putThread.isAlive() || removeThread.isAlive()|| saveThread.isAlive()){
Thread.currentThread().sleep(1000);
}
Exception ex = putThread.getException();
if(putThread.getException()!=null){
checkForConcurrencyException(ex);
}
ex = removeThread.getException();
if(removeThread.getException()!=null){
checkForConcurrencyException(ex);
}
ex = saveThread.getException();
if(saveThread.getException()!=null){
checkForConcurrencyException(ex);
}
}
public class TestThread extends Thread {
TestThread(String name){
super(name);
}
public Exception exception;
public Exception getException(){
return exception;
}
}
@Target(METHOD)
@Retention(RUNTIME)
@JenkinsRecipe(ReplaceHudsonHomeWithCurrentPath.CurrentWorkspacePath.class)
public @interface ReplaceHudsonHomeWithCurrentPath {
String value() default "";
class CurrentWorkspacePath extends JenkinsRecipe.Runner<ReplaceHudsonHomeWithCurrentPath>{
private String paths;
public void decorateHome(JenkinsRule rule, File home){
if(paths.isEmpty())
return;
for(String path : paths.split(",")){
path = path.trim();
try {
File file = new File(home,path);
XmlFile xmlFile = new XmlFile(file);
String content = xmlFile.asString();
content = content.replace("${JENKINS_HOME}", home.getAbsolutePath());
PrintStream stream = new PrintStream(file);
stream.print(content);
stream.close();
} catch (IOException ex) {
Logger.getLogger(DiskUsagePropertyTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
@Override
public void setup(JenkinsRule jenkinsRule, ReplaceHudsonHomeWithCurrentPath recipe) throws Exception {
paths = recipe.value();
}
}
}
class WorkspacePathAnnotation implements Annotation{
public Class<? extends Annotation> annotationType() {
return WorkspacePathAnnotation.class;
}
}
}